package com.sinoair.web;

import com.sinoair.domain.User;
import com.sinoair.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;
import javax.validation.Valid;

@Controller
public class LoginController {


    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private UserService userService;

    @GetMapping(value = "/login")
    public String toPage() {
        return "login";
    }

    /**
     * 用户登录请求
     *
     * @param user
     * @return 跳转页面
     * UnknownAccountException    账号不存在异常
     * IncorrectCredentialsException    当输入密码错误会抛此异常
     * DisabledAccountException（帐号被禁用）
     * LockedAccountException（帐号被锁定）
     * ExcessiveAttemptsException（登录失败次数过多）
     * ExpiredCredentialsException（凭证过期）等
     */
    @PostMapping(value = "login")
    public String submitLogin(@Valid User user,
                              BindingResult bindingResult, boolean rememberMe,
                              RedirectAttributes redirectAttributes) {
        if (bindingResult.hasErrors()) {
            return "redirect:login";
        }
        String username = user.getUsername();
        String password = user.getPassword();
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            logger.info("用户名或者密码为空！");
            redirectAttributes.addFlashAttribute("message", "用户名或者密码为空！");
            return "reditect:login";
        }

        //对用户名和密码进行校验
        UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
        //获取当前的Subject
        Subject currentUser = SecurityUtils.getSubject();

        try {

            logger.info("对用户[" + username + "]进行登录验证..验证开始");
            currentUser.login(token);
            logger.info("对用户[" + username + "]进行登录验证..验证通过");
        } catch (UnknownAccountException uae) {
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,未知账户");
            redirectAttributes.addFlashAttribute("message", "未知账户");
        } catch (IncorrectCredentialsException ice) {
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
            redirectAttributes.addFlashAttribute("message", "密码不正确");
        } catch (LockedAccountException lae) {
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");
            redirectAttributes.addFlashAttribute("message", "账户已锁定");
        } catch (ExcessiveAttemptsException eae) {
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误次数大于5次,账户已锁定");
            redirectAttributes.addFlashAttribute("message", "用户名或密码错误次数大于5次,账户已锁定");
        } catch (DisabledAccountException sae) {
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,帐号已经禁止登录");
            redirectAttributes.addFlashAttribute("message", "帐号已经禁止登录");
        } catch (AuthenticationException ae) {
            //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
            logger.info("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");
            ae.printStackTrace();
            redirectAttributes.addFlashAttribute("message", "用户名或密码不正确");
        }

        //验证是否登录成功
        if (currentUser.isAuthenticated()) {
            logger.info("用户[" + username + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
            //把当前用户放入session
            Session session = currentUser.getSession();
            User tUser = userService.findByUsername(username);
            session.setAttribute("currentUser", tUser);
            return "/index";
        } else {
            token.clear();
            return "redirect:login";
        }
    }


}

